package com.miplus.ccrm.core.service.crd;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.action.FiReliefResVo;
import com.miplus.ccrm.core.controller.vo.conf.MsgTmpResVo;
import com.miplus.ccrm.core.controller.vo.credit.*;
import com.miplus.ccrm.core.controller.vo.file.UploadResVo;
import com.miplus.ccrm.core.mapper.*;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.security.JCommonData;
import com.miplus.ccrm.core.service.ExportService;
import com.miplus.ccrm.core.service.FileService;
import com.miplus.ccrm.core.service.action.CpBatchService;
import com.miplus.ccrm.core.service.action.SmsSendphnService;
import com.miplus.ccrm.core.service.conf.MsgDefineFieldService;
import com.miplus.ccrm.core.service.conf.MsgDefineService;
import com.miplus.ccrm.core.service.conf.SysNamesService;
import com.miplus.ccrm.core.service.cust.ConContactService;
import com.miplus.ccrm.core.service.cust.ConCustomerService;
import com.miplus.ccrm.core.service.file.FiApplyAttService;
import com.miplus.ccrm.core.service.strategy.CfgRuleTaskStepsService;
import com.miplus.ccrm.core.service.strategy.CpCalllistService;
import com.miplus.ccrm.core.service.strategy.CpStrategyService;
import com.miplus.ccrm.core.utils.EnumFiChannel;
import com.miplus.ccrm.core.utils.EnumRuleStepAction;
import com.miplus.ccrm.core.utils.EnumTaskStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author pc
* @description 针对表【fi_task】的数据库操作Service实现
* @createDate 2024-04-08 23:55:42
*/
@Slf4j
@Service
public class FiTaskServiceImpl extends MPJBaseServiceImpl<FiTaskMapper, FiTask>
    implements FiTaskService{

    @Resource
    private FiTaskHistService fiTaskHistService;
    @Resource
    private CpStrategyService cpStrategyService;
    //这里不能在定义fiCreditcasesService了
    @Resource
    private FiCreditcasesMapper fiCreditcasesMapper;
    @Resource
    private CpCalllistService cpCalllistService;
    @Resource
    private CreditAccountMapper creditAccountMapper;
    @Resource
    private ConCustomerService conCustomerService;
    @Resource
    private FiImportHistService fiImportHistService;
    @Resource
    private FiTaskOldhistMapper fiTaskOldhistMapper;
    @Resource
    private CreditCardService creditCardService;
    @Resource
    private SysNamesService sysNamesService;
    @Resource
    private AiListMapper aiListMapper;

    @Resource
    private ExportService exportService;
    @Resource
    private ConContactService conContactService;

    @Resource
    private FiPtpService fiPtpService;

    @Resource
    private FiApplyAttService fiApplyAttService;


    @Resource
    private CpBatchService cpBatchService;

    @Resource
    private SmsSendphnMapper smsSendphnMapper;

    @Resource
    private ObCallCaseMapper obCallCaseMapper;

    @Resource
    private JCommonData jCommonData;

    @Resource
    private MsgDefineFieldService msgDefineFieldService;


    private static String  FITASK_CASETYPE="COLLECT";

    //最大15个自定义字段。
    private static Integer MAX_CUSTOMER_FIELD = 15;

    @Override
    public Integer addTask(String $usrid, String clid, Integer originnumber,
                           Integer channel, Long contactnumber, String phone,String cticallid)
    {
        FiCreditcases ficases=fiCreditcasesMapper.selectById(originnumber);
        return addTask($usrid,clid,originnumber,ficases.getCreditAcct(),channel,
                contactnumber,phone,cticallid,null,null,null,null,null);
    }

    @Override
    public Integer addTask(String usrid, String clid, Integer originnumber,String acctno,Integer channel,Long contactnumber,
                            String phone,String cticallid,String result,String resultdsc,String batchid,Date dodt,String status)
    {//addTask 里面增加result，resultdsc是为了导入催记历史时一次即可，不需要update提交了
        FiTask task=new FiTask();
        task.setClid(clid);
        task.setOriginnumber(originnumber);
        task.setOriginkey(acctno);
        task.setChannel(channel);
        if(contactnumber!=null) {
            task.setContactnumber(contactnumber);
        }
        task.setPhone(phone);
        task.setOrigintype(FITASK_CASETYPE);
        if(JPubUtils.IsEmpty(status)){
            if (JPubUtils.IsEmpty(result)) {
                task.setStatus("O"); //处理中，对应字典：FITASK.STATUS
            } else {
                status = cpStrategyService.getTaskStatus(clid, result);
                task.setStatus(status);
            }
        }
        task.setStatus(status);
        if(JPubUtils.IsNotEmpty(result)) {
            task.setResult(result);
        }
        if (JPubUtils.IsEqual(status, "R") ||
                JPubUtils.IsEqual(status, "F")) {
            task.setSendtimes(1);
            task.setTaskenddt(new Date());
        }else{
            task.setSendtimes(0);
        }
        if(JPubUtils.IsEmpty(task.getStatus())){
            task.setStatus("O");
        }

        if(JPubUtils.IsNotEmpty(cticallid)){
            task.setCticallid(cticallid);
        }
        if(JPubUtils.IsNotEmpty(resultdsc)){
            task.setResultdsc(resultdsc);
        }
        if(JPubUtils.IsNotEmpty(batchid)){
            task.setBatchid(batchid);
        }
        task.setPriority(1000);
        task.setDousr(usrid);
        if(dodt!=null) {
            task.setDodt(dodt);
        }else{
            task.setDodt(new Date());
        }
        task.setCrusr(usrid);
        task.setCrdt(new Date());
        task.setMdusr(usrid);
        task.setMddt(new Date());

        baseMapper.insert(task);

        //写历史记录
        FiTaskHist fiTaskHist=new FiTaskHist();
        BeanUtils.copyProperties(task,fiTaskHist);

        fiTaskHistService.getBaseMapper().insert(fiTaskHist);

        return task.getTasknumber();
    }

    @Override
    public Integer addTask(String $usrid, String clid, Integer originnumber, Integer channel)
    {
        return addTask($usrid,clid, originnumber,channel,null,"",null);
    }

    @Override
    public Integer addTask(String usrid, String clid, String acctno,Integer channel,String phone,
                           String result,String resultdsc,String batchid,Date dodt,String status)
    {
        FiCreditcases ficases=fiCreditcasesMapper.selectOne(
                new QueryWrapper<FiCreditcases>().eq("credit_acct",acctno));
        if(ficases==null){
            log.warn("addTask:acctno={} nofindficase",acctno);
            return 0;
        }

        return addTask(usrid,clid,ficases.getCreditcaseid(),acctno,channel,
                null,phone,null,result,resultdsc,batchid,dodt,status);
    }

    @Override
    public Integer addTask(String usrid, String clid, String acctno,Integer channel,String phone,String batchid, String cticallid)
    {
        FiCreditcases ficases=fiCreditcasesMapper.selectOne(
                new QueryWrapper<FiCreditcases>().eq("credit_acct",acctno));
        if(ficases==null){
            log.warn("addTask:acctno={} nofindficase",acctno);
            return 0;
        }

        return addTask(usrid,clid,ficases.getCreditcaseid(),acctno,channel,
                null,phone,cticallid,null,null,batchid,new Date(),null);
    }

    @Override
    public Integer addTask(String usrid, String clid, Integer originnumber,Integer channel,Long contactnumber,String phone, String result,String resultdsc)
    {
        FiCreditcases ficases=fiCreditcasesMapper.selectOne(
                new QueryWrapper<FiCreditcases>().eq("creditcaseid",originnumber));
        if(ficases==null){
            log.warn("addTask:ficaseid={} noacct",originnumber);
            return 0;
        }

        return addTask(usrid,clid,originnumber,ficases.getCreditAcct(),channel,
                contactnumber,phone,null,result,resultdsc,null,null,null);
    }

    @Override
    public Integer addTask(String $usrid,String clid,Integer originnumber, Integer channel,String result, String resultdsc)
    {
        return addTask($usrid,clid,originnumber,channel,null,null,result,resultdsc);
    }

    @Override
    public int updateStatus(Integer tasknumber, String $usrid,String status)
    {
        if( tasknumber <= 0 )
            return 0;
        FiTask task=new FiTask();
        task.setTasknumber(tasknumber);
        task.setStatus(status);
        task.setMdusr($usrid);
        task.setMddt(new Date());
        int ret=baseMapper.updateById(task);

        task=baseMapper.selectById(tasknumber);
        if(task == null)
            return 0;
        //写历史记录
        FiTaskHist fiTaskHist=new FiTaskHist();
        BeanUtils.copyProperties(task,fiTaskHist);
        fiTaskHistService.getBaseMapper().insert(fiTaskHist);

        return ret;
    }

    @Override
    public String getTaskStatus(Integer tasknumber,String result)
    {
        String ret="O";
        FiTask fiTask=selectJoinOne(FiTask.class,
                new MPJLambdaWrapper<FiTask>()
                        .selectAll(FiTask.class)
                        .eq(FiTask::getTasknumber,tasknumber)
        );
        if(JPubUtils.IsEmpty(fiTask.getClid())){
            ret="F";
        }
        else{
            ret=cpStrategyService.getTaskStatus(fiTask.getClid(),result);
        }
        return ret;
    }

    @Override
    public int saveTask(Integer tasknumber, String $usrid, String result, String resultdsc,
                        String ptpstatus, BigDecimal ptp, Date ptpdt, Date appointdt) {
        return saveTask(tasknumber,$usrid,1,result,resultdsc,ptpstatus,ptp,ptpdt,appointdt,null);
    }

    @Override
    public int saveTask(Integer tasknumber,String $usrid, String result, String resultdsc,
                        String ptpstatus, BigDecimal ptp, Date ptpdt)
    {
        return saveTask(tasknumber,$usrid,1,result,resultdsc,ptpstatus,ptp,ptpdt,null,null);
    }

    @Override
    public int saveTask(Integer tasknumber, String $usrid,Integer sendtimes, String result, String resultdsc,
                        String ptpstatus, BigDecimal ptp, Date ptpdt, Date appointdt,String tkstatus)
    {
        System.out.println("----------------start save task........");
        String status=tkstatus;
        if(JPubUtils.IsEmpty(status)) {
            status=getTaskStatus(tasknumber, result);
        }
        FiTask task= new FiTask();
        task.setTasknumber(tasknumber);
        task.setResult(result);
        if(resultdsc!=null) {
            task.setResultdsc(resultdsc);
        }
        if(JPubUtils.IsNotEmpty(sendtimes)) {
            task.setSendtimes(sendtimes);
        }
        else task.setSendtimes(1);
        if(ptp!=null) {
            task.setPtp(ptp);
        }
        if(ptpdt!=null) {
            task.setPtpdt(ptpdt);
        }
        if(ptpstatus!=null) {
            task.setPtpstatus(ptpstatus);
        }
        task.setStatus(status);
        task.setDousr($usrid);
        task.setDodt(new Date());
        task.setMdusr($usrid);
        task.setMddt(new Date());
        if(appointdt!=null) {
            task.setAppointdt(appointdt);
        }
        if(JPubUtils.IsEqual(status,"R")||
                JPubUtils.IsEqual(status,"F")) {
            task.setTaskenddt(new Date());
        }

        int ret=baseMapper.updateById(task);

        //写历史记录
        FiTask task2=baseMapper.selectById(tasknumber);
        FiTaskHist fiTaskHist=new FiTaskHist();
        BeanUtils.copyProperties(task2,fiTaskHist);

        fiTaskHistService.getBaseMapper().insert(fiTaskHist);

        System.out.println("----------------save task ok ........" + ptpstatus);
//        if(StringUtils.isNotEmpty(ptpstatus)){
//            //记录催记
//            System.out.println("start PtPK...." + ptpstatus);
//            FiPtp fiPtp = new FiPtp();
//            fiPtp.setCreditcaseid(task2.getOriginnumber());
//            fiPtp.setPtpType(ptpstatus);
//            fiPtp.setPtpAmt(ptp);
//            fiPtp.setPtpDate(ptpdt);
//            CmdResVo cmdResVo = fiPtpService.addPtp( fiPtp, $usrid);
//            System.out.println("ret msg:" + cmdResVo.getKeyId());
//        }
        return ret;
    }

    @Override
    public CmdResVo addDialTask(String $usrid, TaskCallAddVo paras)
    {
        String clid=paras.getClid();
        if(JPubUtils.IsEmpty(clid)){
            clid="SYS_CALL";
        }
        Integer channel=paras.getChannel();
        if(JPubUtils.IsEmpty(channel)){
            channel=EnumFiChannel.Phone.value;
        }

        String phn=paras.getPhone();
        if(phn.indexOf("*")>0){//2024-07-08
            phn=conContactService.getPhone(paras.getContactnumber());

            log.info("addDialTask：Phone={}->{}",paras.getPhone(),phn);
        }
        //修改，想保存到Redis中，后SaveDialTask API中保存到task表中。 20250508
//        Integer tasknumber=addTask($usrid,clid,paras.getFicaseid(),channel,
//                paras.getContactnumber(),phn,paras.getCticallid()
//        );

//      return new CmdResVo(1,tasknumber.toString());

        FiTask fiTask = new FiTask();
        fiTask.setClid(clid);
        fiTask.setPhone(phn);
        fiTask.setContactnumber(paras.getContactnumber());
        fiTask.setCticallid(paras.getCticallid());
        fiTask.setChannel(channel);
        fiTask.setOriginnumber(paras.getFicaseid());
        fiTask.setOrigintype("COLLECT");
        fiTask.setCrdt( new Date());
        fiTask.setCrusr($usrid);
        log.info("addDialTask：{} ",fiTask);
        int iRand = new Random().nextInt(10000) + 1;
        String rkey = "call." + paras.getFicaseid() + "." + iRand;
        jCommonData.setData(rkey,fiTask,JPubUtils.distExpiration*2);
        log.info("addDialTask to Redis：key: {} ",rkey);
        return new CmdResVo(1, String.valueOf(iRand));
    }

    @Override
    public CmdResVo saveDialTask(String $usrid, TaskCallSaveVo paras)
    {
        System.out.println("SaveDialTask--------------------------------------");
        //修改。从redis 获取callid，然后更新。
//        int ret=saveTask(paras.getTasknumber(),$usrid,paras.getResult(),paras.getResultdsc(),
//                paras.getPtpstatus(),paras.getPtp(),paras.getPtpdt(),paras.getAppointdt());
        if(ObjectUtils.isNull(paras.getFicaseid()) || ObjectUtils.isNull(paras.getTasknumber()))
            return new CmdResVo(-1,"参数错误，案件和任务没有值");
        Integer taskNumber = paras.getTasknumber();
        //格式：call.案件ID.任务ID
        String rkey = "call." + paras.getFicaseid() + "." + paras.getTasknumber();
        Object o = jCommonData.getData(rkey);
        if( o == null){
            log.info("SaveDialTask: no get object. key:{}. update task direct. ",rkey);
            saveTask(paras.getTasknumber(),$usrid,paras.getResult(),paras.getResultdsc(),
                paras.getPtpstatus(),paras.getPtp(),paras.getPtpdt(),paras.getAppointdt());
        }
        else{
            jCommonData.delData(rkey);
            taskNumber = addDialTask($usrid, (FiTask) o, paras);
        }
        log.info("SaveDialTask Task OK. tasknumber:{} ",taskNumber);
        //增加附件功能
        if( paras.getTaskFiles() != null )
        {
            fiApplyAttService.AddApplyFile(taskNumber, "" + EnumFiChannel.Phone.value,"other", paras.getTaskFiles());
        }
        if(paras.getRecordFiles() != null)
        {
            fiApplyAttService.AddApplyFile(taskNumber, "" + EnumFiChannel.Phone.value,"record", paras.getRecordFiles());
        }
        System.out.println("SaveDialTask OK------------------------------------");
        return new CmdResVo(1, taskNumber.toString());
    }
    private Integer addDialTask(String usrid, FiTask fiTask, TaskCallSaveVo paras)
    {
//        public Integer addTask(String usrid, String clid, Integer originnumber,String acctno,Integer channel,Long contactnumber,
//            String phone,String cticallid,String result,String resultdsc,String batchid,Date dodt,String status)
        fiTask.setAppointdt( paras.getAppointdt());
        fiTask.setDodt( new Date());
        fiTask.setMddt( new Date());
        fiTask.setMdusr( usrid );
        fiTask.setResult( paras.getResult());
        fiTask.setResultdsc(paras.getResultdsc());

        fiTask.setPtp( paras.getPtp());
        fiTask.setPtpdt( paras.getPtpdt());
        fiTask.setPtpstatus( paras.getPtpstatus());
        fiTask.setPriority(1000);
        fiTask.setSendtimes(1);
        fiTask.setStatus(cpStrategyService.getTaskStatus(fiTask.getClid(),paras.getResult()));
        save(fiTask);
        FiTaskHist fiTaskHist=new FiTaskHist();
        BeanUtils.copyProperties(fiTask,fiTaskHist);
        fiTaskHistService.getBaseMapper().insert(fiTaskHist);

        return fiTask.getTasknumber();
    }
    @Override
    public CmdResVo addSmsTask(String $usrid, TaskSmsAddVo paras)
    {
        String clid=paras.getClid();
        if(JPubUtils.IsEmpty(clid)){
            clid="SYS_SMS";
        }
        Integer channel=paras.getChannel();
        if(JPubUtils.IsEmpty(channel)){
            channel=EnumFiChannel.Sms.value;
        }
        String phn=paras.getPhone();
        if(phn.indexOf("*")>0){//2024-07-08
            phn=conContactService.getPhone(paras.getContactnumber());
            log.info("addSmsTask：Phone={}->{}",paras.getPhone(),phn);
        }

        Integer tasknumber=addTask($usrid,clid,paras.getFicaseid(),channel,
                paras.getContactnumber(),phn,null
        );

        return new CmdResVo(1,tasknumber.toString());
    }

    @Override
    public CmdResVo saveSmsTask(String $usrid, TaskSmsSaveVo paras)
    {
        int ret=saveTask(paras.getTasknumber(),$usrid,paras.getResult(),paras.getResultdsc(),
                null,null,null);

        return new CmdResVo(ret,paras.getTasknumber().toString());
    }

    @Override
    public List<FiTaskCurrVo> getCurrentTask(Integer ficaseid)
    {//案件号一样，可以多次外访，但是状态是N,O,P的只有一个
        return selectJoinList(FiTaskCurrVo.class,
                new MPJLambdaWrapper<FiTask>()
                    .selectAs(FiTask::getStatus,FiTaskCurrVo::getState)
                    .selectAs("fun_getnames('CAMPAIGN.CHANNEL',cp.channel)",FiTaskCurrVo::getChannelname)
                    .leftJoin(CpCalllist.class,"cp",CpCalllist::getClid,FiTask::getClid)
                    .select(FiTask::getTasknumber,FiTask::getClid,FiTask::getStatus)
                    .select(CpCalllist::getName,CpCalllist::getChannel,CpCalllist::getWfid)
                    .in(FiTask::getStatus,"O","N","P")
                    .eq(CpCalllist::getApptype,"1")
                    .eq(FiTask::getOriginnumber,ficaseid)
        );
    }

    @Override
    public IPage<FiTaskResVo> taskHist(JSysUser user, FiTaskReqVo paras)
    {
        String $usrid=user.getUsrid();
        String cardnos=JPubUtils.getInString(paras.getCardnolist());
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        String cardstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_CARD);
        String distUsrId = $usrid;
        if(ObjectUtils.isNotNull(paras.getExpidlist())){
            phnstar = "1";
            idstar = "1";
            cardstar = "1";

        }
        //2024-07-24
        boolean viewAllCase=JUsrPerm.viewAllFiCase(user);
        //数据库尽量不要使用函数，否则慢,尤其TDSQL
        //.apply("fi_hasFiCaseView({0},t.creditcaseid,t.status,t.sendtodept,t.sendtousr)>0", $usrid)
        //      log.info("getQueryWrapper:viewAllCase={},iscock={}",viewAllCase,iscock);
        if(ObjectUtils.isNotNull(paras.getFicaseid()))
            viewAllCase = true;

        boolean viewGrpFiCase = false;
        if(!viewAllCase && user.getMgrgrplist().size()>0)
            viewGrpFiCase = true;

        List<Integer>tasknumberList=new ArrayList<>();

        IPage<FiTaskResVo> fiTaskResVoIPage=selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                FiTaskResVo.class,
                new MPJLambdaWrapper<FiTask>()
//                    .selectAs("DATE_FORMAT(t.crdt,'%Y-%m-%d %H:%i:%s')",FiTaskResVo::getCrdt)
//                    .selectAs("DATE_FORMAT(t.appointdt,'%Y-%m-%d %H:%i:%s')",FiTaskResVo::getAppointdt)
//                    .selectAs("DATE_FORMAT(t.dodt,'%Y-%m-%d %H:%i:%s')",FiTaskResVo::getDodt)
//                    .selectAs("fun_getnames('CAMPAIGN.CHANNEL',t.channel)",FiTaskResVo::getChannel)
//                    .selectAs("fun_getnames('FITASK.STATUS',t.status)",FiTaskResVo::getStatus)
//                    .selectAs("fun_getnames('CON.RELATION',ct.relational)",FiTaskResVo::getRelational)
//                    .selectAs("fun_getnames('FI.REPAY.WILL',t.ptpstatus)",FiTaskResVo::getPtpstatusdsc)
//                    .selectAs(FiTask::getOriginnumber,FiTaskResVo::getFicaseid)
//                    .selectAs("fun_getnames('COLLECT.STATUS',fi.status)",FiTaskResVo::getFicasestatus)
//                    .selectAs("ct.name",FiTaskResVo::getContactname)
//                    .selectAs("fi_gettaskresult(t.clid,t.result)",FiTaskResVo::getResult)
//                    .selectAs("concat(tr.filepath,tr.filename)",FiTaskResVo::getRecordurl)
//                    .selectAs(String.format("fi_starSecu('%s','%s',t.phone,'%s')",$usrid,JUsrPerm.DISSTAR_PHN,phnstar),FiTaskResVo::getPhone)
//                    .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')", $usrid, JUsrPerm.DISSTAR_IDNO, idstar), FiTaskResVo::getOpenacctcertno)
//                    .selectAs(String.format("fi_starSecu('%s','%s',cda.crdt_card_repe_no,'%s')", $usrid, JUsrPerm.DISSTAR_CARD, cardstar), FiTaskResVo::getCrdtCardRepeNo)
                    .leftJoin(FiCreditcases.class,"fi",FiCreditcases::getCreditcaseid,FiTask::getOriginnumber)
                    .leftJoin(ConCustomer.class,"cu",ConCustomer::getCustomernumber,FiCreditcases::getCustomernumber)
                    .leftJoin("sys_user u on u.usrid = t.crusr")
//                    .leftJoin(ConContact.class,"ct",ConContact::getContactnumber,FiTask::getContactnumber)
//                    .leftJoin("t_recorder tr on tr.callid=t.cticallid")
//                    .leftJoin(CreditAccount.class,"cda",CreditAccount::getAcct,FiTask::getOriginkey)
                    .select(FiTask::getTasknumber,FiTask::getResultdsc,
                            FiTask::getDousr,FiTask::getPriority,
                            FiTask::getPtp,FiTask::getPtpdt,FiTask::getCticallid,FiTask::getIndividualTag
                    )
                    .select(FiTask::getTasknumber)
                    .select(ConCustomer::getCustname)
                //    .apply("fc_hasUsrInMgr(t.crusr,{0})>0",$usrid)

                    .eq(JPubUtils.IsNotEmpty(paras.getFicaseid()),FiTask::getOriginnumber,paras.getFicaseid())
                    .eq(JPubUtils.IsNotEmpty(paras.getChannel()),FiTask::getChannel,paras.getChannel())
                    .eq(JPubUtils.IsNotEmpty(paras.getPhone()),FiTask::getPhone,paras.getPhone())
                    .eq(JPubUtils.IsNotEmpty(paras.getCustname()),ConCustomer::getCustname,paras.getCustname())
                    .eq(JPubUtils.IsNotEmpty(paras.getPtpstatus()),FiTask::getPtpstatus,paras.getPtpstatus())
                    .in(JPubUtils.IsNotEmpty(paras.getCrusr()),FiTask::getCrusr,paras.getCrusr())
                        .in(JPubUtils.IsNotEmpty(paras.getGrpid()),"u.groups",paras.getGrpid())
                        .eq(JPubUtils.IsNotEmpty(paras.getBatchid()),FiTask::getBatchid,paras.getBatchid())
                    .eq(JPubUtils.IsNotEmpty(paras.getOpenacctcertno()),ConCustomer::getOpenacctcertno,paras.getOpenacctcertno())
                    .apply(JPubUtils.IsNotEmpty(paras.getResult()),"fi_gettaskresult(t.clid,t.result)={0}",paras.getResult())
                    .between(JPubUtils.IsNotEmpty(paras.getStartdt()), FiTask::getCrdt,JPubUtils.StringToDate(paras.getStartdt()),JPubUtils.StringToDate(paras.getEnddt()))
                    .like(JPubUtils.IsNotEmpty(paras.getResultdsc()),FiTask::getResultdsc,paras.getResultdsc())
                    .in(JPubUtils.IsNotEmpty(paras.getOpenacctcertnolist()), ConCustomer::getOpenacctcertno, paras.getOpenacctcertnolist())
                    .exists(JPubUtils.IsNotEmpty(paras.getCardno()), String.format("select 1 from credit_card crd where crd.acct=t.originkey and crd.card_no='%s'", paras.getCardno()))
                    .exists(JPubUtils.IsNotEmpty(cardnos), String.format("select 1 from credit_card crd where crd.acct=t.originkey and crd.card_no in ('%s')", cardnos))
                    .in(viewGrpFiCase,"u.groups",user.getMgrgrplist())
                    .eq(!viewGrpFiCase && !viewAllCase, FiTask::getCrusr,$usrid)
                    .orderByDesc(JPubUtils.IsNotEmpty(paras.getFicaseid()),"ifnull(t.priority,1000)")
                    .orderByDesc(FiTask::getTasknumber)
            ).convert(x->{
                x.setTaskFiles(fiApplyAttService.GetApplyFile( x.getTasknumber(),"" + EnumFiChannel.Phone.value,"other"));
                x.setRecordFiles(fiApplyAttService.GetApplyFile( x.getTasknumber(),"" + EnumFiChannel.Phone.value,"record"));
                tasknumberList.add(x.getTasknumber());
            return x;
        });

//        log.info("tasknumberList:{}",tasknumberList);
        if(tasknumberList!=null && tasknumberList.size()>0){

            Map<Integer, FiTaskResVo> fiTaskList = selectJoinList(FiTaskResVo.class,
                    new MPJLambdaWrapper<FiTask>()
                            .selectAs("DATE_FORMAT(t.crdt,'%Y-%m-%d %H:%i:%s')", FiTaskResVo::getCrdt)
                            .selectAs("DATE_FORMAT(t.appointdt,'%Y-%m-%d %H:%i:%s')", FiTaskResVo::getAppointdt)
                            .selectAs("DATE_FORMAT(t.dodt,'%Y-%m-%d %H:%i:%s')", FiTaskResVo::getDodt)
                            .selectAs("t.channel", FiTaskResVo::getChannelDsc)
                            .selectAs("fun_getnames('CAMPAIGN.CHANNEL',t.channel)", FiTaskResVo::getChannel)
                            .selectAs("fun_getnames('FITASK.STATUS',t.status)", FiTaskResVo::getStatus)
                            .selectAs("fun_getnames('CON.RELATION',ct.relational)", FiTaskResVo::getRelational)
                            .selectAs("fun_getnames('FI.REPAY.WILL',t.ptpstatus)", FiTaskResVo::getPtpstatusdsc)
                            .selectAs("if(sysu.usrid is null,t.crusr,CONCAT(sysu.`NAME`,CONCAT('(',sysu.usrid,')')))", FiTaskResVo::getCrusr)
                            .selectAs(String.format("fi_starSecu('%s','%s',t.phone,'%s')", distUsrId,JUsrPerm.DISSTAR_PHN, phnstar), FiTaskResVo::getPhone)
                            .selectAs(FiTask::getOriginnumber, FiTaskResVo::getFicaseid)
                            .selectAs("fun_getnames('COLLECT.STATUS',fi.status)", FiTaskResVo::getFicasestatus)
                            .selectAs("ct.name", FiTaskResVo::getContactname)
                            .selectAs("fi_gettaskresult(t.clid,t.result)", FiTaskResVo::getResult)
                            .selectAs("concat(tr.filepath,tr.filename)", FiTaskResVo::getRecordurl)
                            .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')", distUsrId,JUsrPerm.DISSTAR_IDNO, idstar), FiTaskResVo::getOpenacctcertno)
                            .selectAs(String.format("fi_starSecu('%s','%s',cda.crdt_card_repe_no,'%s')", distUsrId, JUsrPerm.DISSTAR_CARD, cardstar), FiTaskResVo::getCrdtCardRepeNo)
                            .selectAs("sgrp.grpname", FiTaskResVo::getGrpName)

                            .select(FiTask::getTasknumber)
                            .leftJoin("sys_user sysu on sysu.usrid=t.crusr")
                            .leftJoin("sys_grp sgrp on sgrp.grpid = sysu.groups")
                            .leftJoin(FiCreditcases.class, "fi", FiCreditcases::getCreditcaseid, FiTask::getOriginnumber)
                            .leftJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, FiCreditcases::getCustomernumber)
                            .leftJoin(CreditAccount.class, "cda", CreditAccount::getAcct, FiTask::getOriginkey)
                            .leftJoin("t_recorder tr on tr.callid=t.cticallid")
                            .leftJoin(ConContact.class, "ct", ConContact::getContactnumber, FiTask::getContactnumber)
                            .in(FiTask::getTasknumber, tasknumberList)
            ).stream().collect(Collectors.toMap(item -> item.getTasknumber(), item -> item));

            log.info("fiTaskList:{}",fiTaskList);
            fiTaskResVoIPage.convert(x->{
                x.setCrdt(fiTaskList.get(x.getTasknumber()).getCrdt());
                x.setAppointdt(fiTaskList.get(x.getTasknumber()).getAppointdt());
                x.setDodt(fiTaskList.get(x.getTasknumber()).getDodt());
                x.setChannel(fiTaskList.get(x.getTasknumber()).getChannel());
                x.setChannelDsc(fiTaskList.get(x.getTasknumber()).getChannelDsc());
                x.setStatus(fiTaskList.get(x.getTasknumber()).getStatus());
                x.setRelational(fiTaskList.get(x.getTasknumber()).getRelational());
                x.setPtpstatusdsc(fiTaskList.get(x.getTasknumber()).getPtpstatusdsc());
                x.setCrusr(fiTaskList.get(x.getTasknumber()).getCrusr());
                x.setPhone(fiTaskList.get(x.getTasknumber()).getPhone());
                x.setFicaseid(fiTaskList.get(x.getTasknumber()).getFicaseid());
                x.setFicasestatus(fiTaskList.get(x.getTasknumber()).getFicasestatus());
                x.setContactname(fiTaskList.get(x.getTasknumber()).getContactname());
                x.setResult(fiTaskList.get(x.getTasknumber()).getResult());
                x.setRecordurl(fiTaskList.get(x.getTasknumber()).getRecordurl());
                x.setOpenacctcertno(fiTaskList.get(x.getTasknumber()).getOpenacctcertno());
                x.setCrdtCardRepeNo(fiTaskList.get(x.getTasknumber()).getCrdtCardRepeNo());
                x.setGrpName(fiTaskList.get(x.getTasknumber()).getGrpName());
                return x;
            });
        }


        return fiTaskResVoIPage;


//        IPage<FiTaskResVo> fiTaskResVoIPage=selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
//                FiTaskResVo.class,
//                new MPJLambdaWrapper<FiTask>()
//                        .selectAs("DATE_FORMAT(t.crdt,'%Y-%m-%d %H:%i:%s')",FiTaskResVo::getCrdt)
//                        .selectAs("DATE_FORMAT(t.appointdt,'%Y-%m-%d %H:%i:%s')",FiTaskResVo::getAppointdt)
//                        .selectAs("DATE_FORMAT(t.dodt,'%Y-%m-%d %H:%i:%s')",FiTaskResVo::getDodt)
//                        .selectAs("fun_getnames('CAMPAIGN.CHANNEL',t.channel)",FiTaskResVo::getChannel)
//                        .selectAs("fun_getnames('FITASK.STATUS',t.status)",FiTaskResVo::getStatus)
//                        .selectAs("fun_getnames('CON.RELATION',ct.relational)",FiTaskResVo::getRelational)
//                        .selectAs("fun_getnames('FI.REPAY.WILL',t.ptpstatus)",FiTaskResVo::getPtpstatusdsc)
//                        .selectAs(FiTask::getOriginnumber,FiTaskResVo::getFicaseid)
//                        .selectAs("fun_getnames('COLLECT.STATUS',fi.status)",FiTaskResVo::getFicasestatus)
//                        .selectAs("ct.name",FiTaskResVo::getContactname)
//                        .selectAs("fi_gettaskresult(t.clid,t.result)",FiTaskResVo::getResult)
//                        .selectAs("concat(tr.filepath,tr.filename)",FiTaskResVo::getRecordurl)
//                        .selectAs(String.format("fi_starSecu('%s','%s',t.phone,'%s')",$usrid,JUsrPerm.DISSTAR_PHN,phnstar),FiTaskResVo::getPhone)
//                        .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')", $usrid, JUsrPerm.DISSTAR_IDNO, idstar), FiTaskResVo::getOpenacctcertno)
//                        .selectAs(String.format("fi_starSecu('%s','%s',cda.crdt_card_repe_no,'%s')", $usrid, JUsrPerm.DISSTAR_CARD, cardstar), FiTaskResVo::getCrdtCardRepeNo)
//                        .leftJoin(FiCreditcases.class,"fi",FiCreditcases::getCreditcaseid,FiTask::getOriginnumber)
//                        .leftJoin(ConCustomer.class,"cu",ConCustomer::getCustomernumber,FiCreditcases::getCustomernumber)
//                        .leftJoin(ConContact.class,"ct",ConContact::getContactnumber,FiTask::getContactnumber)
//                        .leftJoin("t_recorder tr on tr.callid=t.cticallid")
//                        .leftJoin(CreditAccount.class,"cda",CreditAccount::getAcct,FiTask::getOriginkey)
//                        .select(FiTask::getTasknumber,FiTask::getCrusr,FiTask::getResultdsc,
//                                FiTask::getDousr,FiTask::getPriority,
//                                FiTask::getPtp,FiTask::getPtpdt,FiTask::getCticallid
//                        )
//                        .select(ConCustomer::getCustname)
//                        .apply("fc_hasUsrInMgr(t.crusr,{0})>0",$usrid)
//                        .eq(JPubUtils.IsNotEmpty(paras.getFicaseid()),FiTask::getOriginnumber,paras.getFicaseid())
//                        .eq(JPubUtils.IsNotEmpty(paras.getChannel()),FiTask::getChannel,paras.getChannel())
//                        .eq(JPubUtils.IsNotEmpty(paras.getPhone()),FiTask::getPhone,paras.getPhone())
//                        .eq(JPubUtils.IsNotEmpty(paras.getCustname()),ConCustomer::getCustname,paras.getCustname())
//                        .eq(JPubUtils.IsNotEmpty(paras.getPtpstatus()),FiTask::getPtpstatus,paras.getPtpstatus())
//                        .in(JPubUtils.IsNotEmpty(paras.getCrusr()),FiTask::getCrusr,paras.getCrusr())
//                        .eq(JPubUtils.IsNotEmpty(paras.getBatchid()),FiTask::getBatchid,paras.getBatchid())
//                        .eq(JPubUtils.IsNotEmpty(paras.getOpenacctcertno()),ConCustomer::getOpenacctcertno,paras.getOpenacctcertno())
//                        .apply(JPubUtils.IsNotEmpty(paras.getResult()),"fi_gettaskresult(t.clid,t.result)={0}",paras.getResult())
//                        .between(JPubUtils.IsNotEmpty(paras.getStartdt()), FiTask::getCrdt,JPubUtils.StringToDate(paras.getStartdt()),JPubUtils.StringToDate(paras.getEnddt()))
//                        .like(JPubUtils.IsNotEmpty(paras.getResultdsc()),FiTask::getResultdsc,paras.getResultdsc())
//                        .in(JPubUtils.IsNotEmpty(paras.getOpenacctcertnolist()), ConCustomer::getOpenacctcertno, paras.getOpenacctcertnolist())
//                        .exists(JPubUtils.IsNotEmpty(paras.getCardno()), String.format("select 1 from credit_card crd where crd.acct=t.originkey and crd.card_no='%s'", paras.getCardno()))
//                        .exists(JPubUtils.IsNotEmpty(cardnos), String.format("select 1 from credit_card crd where crd.acct=t.originkey and crd.card_no in ('%s')", cardnos))
//                        .orderByAsc(FiTask::getPriority)
//                        .orderByDesc(FiTask::getDodt)
//        ).convert(x->{
//            x.setTaskFiles(fiApplyAttService.GetApplyFile( x.getTasknumber(),"" + EnumFiChannel.Phone.value,"other"));
//            x.setRecordFiles(fiApplyAttService.GetApplyFile( x.getTasknumber(),"" + EnumFiChannel.Phone.value,"record"));
//            return x;
//        });
    }

    @Override
    public CrdCmdResVo crdCardFrozen(String $usrid, CrdFrozenReqVo paras)
    { //账户管制
        String clid=paras.getClid();
        if(JPubUtils.IsEmpty(clid)){
            clid="SYS_CARDFRZ";
        }
        Integer channel=paras.getChannel();
        if(JPubUtils.IsEmpty(channel)){
            channel=EnumFiChannel.Frozen.value;
        }
        //卡号客户端是加密的
        FiCreditcases creditcases=fiCreditcasesMapper.selectById(paras.getFicaseid());
        CreditAccount account=creditAccountMapper.selectOne(
                new QueryWrapper<CreditAccount>().eq("acct",creditcases.getCreditAcct())
        );
        String cardno=account.getCrdtCardRepeNo();
        String opt=sysNamesService.getNamesDsc("CREDIT.FROZEN.OPT",paras.getCrdopt());
        CrdCmdResVo crdCmdResVo=CrdCommand.crdCardFrozen(
                cardno,paras.getCrdopt(),paras.getCrdsts(),paras.getCrdorg()
        );

        addTask($usrid,clid,paras.getFicaseid(),channel,
                crdCmdResVo.getRespCode(),
                opt+"("+paras.getCrdsts()+"):"+crdCmdResVo.getRespCodeDesc()
        );

        return crdCmdResVo;
    }

    @Override
    public CrdCmdResVo crdCardDeduction(String $usrid, CrdDeduReqVo paras)
    { //卡划扣
        String clid=paras.getClid();
        if(JPubUtils.IsEmpty(clid)){
            clid="SYS_CARDDED";
        }
        Integer channel=paras.getChannel();
        if(JPubUtils.IsEmpty(channel)){
            channel=EnumFiChannel.Deduction.value;
        }
        //需要取，传的cardno参数是加密带星的
        FiCreditcases fi=fiCreditcasesMapper.selectById(paras.getFicaseid());
        ConCustomer cu=conCustomerService.getById(fi.getCustomernumber());
        String cardno=paras.getCardno();
        if(cardno.indexOf("*")>=0) {//如果不带*，直接使用，2024-06-06
            cardno=cu.getDebitcardno();
        }
        String crdcardno=creditCardService.getAccOpenLastCardNo(fi.getCreditAcct());
        CrdCmdResVo crdCmdResVo=CrdCommand.crdCarDeduction(cardno,crdcardno,paras.getAmount());

        addTask($usrid,clid,paras.getFicaseid(),channel,
                crdCmdResVo.getRespCode(),"划扣金额："+paras.getAmount().toString()
        );

        return crdCmdResVo;
    }

    @Override
    public CmdResVo taskTopSet(Integer tasknumber,Integer toppos)
    {
        FiTask fi=baseMapper.selectById(tasknumber);
        List<FiTask> taskList=selectJoinList(FiTask.class,
                new MPJLambdaWrapper<FiTask>()
                        .select(FiTask::getOriginnumber,FiTask::getPriority)
                        .gt(FiTask::getPriority,1000)
                        .isNotNull(FiTask::getOriginnumber)
                        .eq(FiTask::getOriginnumber,fi.getOriginnumber())
        );
        if(taskList.size()>=3){
            throw new ServiceException(EnumRCode.TopMix.value, EnumRCode.TopMix.name);
        }
        fi=new FiTask();
        fi.setTasknumber(tasknumber);
        if(JPubUtils.IsEmpty(toppos)){
            fi.setPriority(1001);
            for(FiTask upfi:taskList){
                if(ObjectUtils.isNull(upfi.getPriority()))
                    upfi.setPriority(1001);
                else
                    upfi.setPriority(upfi.getPriority()+1);
                baseMapper.updateById(upfi);
            }
        }else{
            fi.setPriority(1000 + toppos);
        }

        int ret=baseMapper.updateById(fi);

        return new CmdResVo(ret,tasknumber.toString());
    }

    @Override
    public CmdResVo taskTopCancel(Integer tasknumber)
    {
        FiTask fi=new FiTask();
        fi.setTasknumber(tasknumber);
        fi.setPriority(1000);

        int ret=baseMapper.updateById(fi);

        return new CmdResVo(ret,tasknumber.toString());
    }

    @Override
    @Transactional
    public ImpResultVo impTaskList(String $usrid,FiTaskImpVo paras)
    {//批量导入离线催记
        SimpleDateFormat sdf=new SimpleDateFormat("yyMMddHHmmssSSS");
        String batchid ="L"+sdf.format(new Date());

        String tempid=paras.getTempid();
        if(JPubUtils.IsEmpty(tempid)){
            tempid="offtask";
        }

        int ret=0;
        ImpResultVo impResultVo=new ImpResultVo();
        List<String> fails=new LinkedList<>();
        log.info("impTaskList:batchid={},Count={}",batchid,paras.getAddVoList().size());

        for(FiTaskAddVo fiAdd:paras.getAddVoList()){
            String acctno=fiAdd.getAcctno().trim();
            if(JPubUtils.IsTrimEmpty(fiAdd.getChannel())){
                log.warn("impTaskList:channel null:{}",fiAdd.getChannel());
                fails.add(acctno+":没有催记动作");
                continue;
            }
            String channel=fiAdd.getChannel().trim();
            EnumFiChannel fiChannel=EnumFiChannel.AsFiChannel(channel);
            if(fiChannel==EnumFiChannel.Unknow){//最好前台页面做一下校验提醒
                log.warn("impTaskList:nochannel {}",channel);
                fails.add(acctno+":没对应催记动作:"+channel);
                continue;
            }
            Date dodt=JPubUtils.StringToDate(fiAdd.getDodt());
            if(dodt==null) {
                dodt = new Date();
            }
            String tkstatus=null;
            String ccc=null;
            String clid = "SYS_CALL";
            if(JPubUtils.IsNotEmpty(fiAdd.getResult())&&JPubUtils.IsNotEmpty(clid)) {
                ccc = cpStrategyService.getCcc(clid, fiAdd.getResult().trim());
            }
            else tkstatus= EnumTaskStatus.R.toString();

            String usrid=fiAdd.getDousrid();
            if(JPubUtils.IsTrimEmpty(usrid)){
                usrid=$usrid;
            }
            log.info("impTaskList:batchid={},clid={},acctno={},ccc={},tkstatus={},channel={}({})",
                    batchid,clid,acctno,ccc,tkstatus,channel,fiChannel.value
            );
            addTask(usrid,clid,acctno,fiChannel.value,
                    JPubUtils.Trim(fiAdd.getPhone()),ccc,JPubUtils.Trim(fiAdd.getRemark()),batchid,dodt,tkstatus
            );
            ret++;
        }

        if(ret>0) {
            fiImportHistService.AddImportHist(batchid, paras.getBatchdsc(), $usrid,
                    tempid, paras.getFilename(),
                    paras.getAddVoList().size(), ret);
        }
        impResultVo.setBatchid(batchid);
        impResultVo.setOkcnt(ret);
        impResultVo.setFailcnt(fails.size());
        impResultVo.setFaillist(fails);
        return impResultVo;
    }

    @Override
    @Transactional
    public ImpResultVo impTaskCmdList(String $usrid,TaskCmdImpVo paras)
    {//批量增加（导入）导入催收函/诉讼/支付令，记录催记
        SimpleDateFormat sdf=new SimpleDateFormat("yyMMddHHmmssSSS");
        String batchid = "C"+sdf.format(new Date());

        int ret=0;
        ImpResultVo impResultVo=new ImpResultVo();
        List<String> fails=new LinkedList<>();
        EnumFiChannel fiChannel=EnumFiChannel.AsFiChannelBy(paras.getTempid());
        log.info("impTaskCmdList:tempid={},batchid={},Count={},Channel={}",
                paras.getTempid(),batchid,paras.getAddVoList().size(),fiChannel
        );
        if(fiChannel==EnumFiChannel.Unknow){
            throw new ServiceException(EnumRCode.NoChannel.value, EnumRCode.NoChannel.name);
        }
        String clid = cpCalllistService.getClid(fiChannel.value);
        for(TaskCmdAddVo fiAdd : paras.getAddVoList()){
            String acctno=fiAdd.getAcctno().trim();
            CreditAccount account=creditAccountMapper.selectOne(
                    new QueryWrapper<CreditAccount>().eq("acct",acctno)
            );
            if(account==null){
                log.warn("impTaskCmdList:nofind acctno={}",acctno);
                fails.add(acctno);
                continue;
            }
            Date dodt=JPubUtils.StringToDate(fiAdd.getDodt());
            if(dodt==null) {
                dodt = new Date();
            }
            String tkstatus=null;
            String ccc=null;
            if(JPubUtils.IsNotEmpty(fiAdd.getResult())){
                if(JPubUtils.IsNotEmpty(clid)) {
                    ccc = cpStrategyService.getCcc(clid, fiAdd.getResult().trim());
                }
                else{
                    ccc=fiAdd.getResult().trim();
                }
            }
            if(JPubUtils.IsEmpty(clid)){
                tkstatus=EnumTaskStatus.R.toString();
            }
            String custno=account.getCustNo();
            log.info("impTaskCmdList:batchid={},acctno={},ccc={},tkstatus={},channel={},addtag={}",
                    batchid,acctno,ccc,tkstatus,fiChannel.value,fiChannel.toString().toUpperCase()
            );
            addTask($usrid,clid,acctno,fiChannel.value,
                    null,ccc,JPubUtils.Trim(fiAdd.getRemark()),batchid,dodt,tkstatus
            );

            if(fiChannel!=EnumFiChannel.Letter) { //催收不打标签2024-05-20
                conCustomerService.addTag(custno, "SYS", fiChannel.toString().toUpperCase(), batchid);
            }

            ret++;
        }
        if(ret>0) {
            fiImportHistService.AddImportHist(batchid,paras.getBatchdsc(), $usrid,
                    paras.getTempid(), paras.getFilename(),
                    paras.getAddVoList().size(), ret);
        }
        impResultVo.setBatchid(batchid);
        impResultVo.setOkcnt(ret);
        impResultVo.setFailcnt(fails.size());
        impResultVo.setFaillist(fails);

        return impResultVo;
    }

    @Override
    @Transactional
    public CmdResVo delImpTaskList(TaskBatchDelVo paras)
    {
        String tempid=paras.getTempid();
        int ret=0;
        if(JPubUtils.IsEqual(tempid,"histtask")){
            fiTaskOldhistMapper.delete(new QueryWrapper<FiTaskOldhist>()
                    .eq("batchid",paras.getBatchid())
            );
        }
        else {
            ret = baseMapper.delete(new QueryWrapper<FiTask>()
                    .eq("batchid", paras.getBatchid())
            );
            fiTaskHistService.getBaseMapper().delete(new QueryWrapper<FiTaskHist>()
                    .eq("batchid", paras.getBatchid())
            );
            if (JPubUtils.IsEqual(tempid, "letter") ||
                    JPubUtils.IsEqual(tempid, "law") ||
                    JPubUtils.IsEqual(tempid, "paycmd")) {
                conCustomerService.delTag(paras.getBatchid());
            }
        }

        fiImportHistService.getBaseMapper().delete(
                new QueryWrapper<FiImportHist>().eq("batchid",paras.getBatchid())
        );

        return new CmdResVo(ret,paras.getBatchid());
    }

    @Override
    @Transactional
    public ImpResultVo impHistTaskList(String $usrid,HistTaskImpVo paras)
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyMMddHHmmssSSS");
        String batchid ="H"+sdf.format(new Date());

        String tempid=paras.getTempid();
        if(JPubUtils.IsEmpty(tempid)){
            tempid="histtask";
        }

        int ret=0;
        ImpResultVo impResultVo=new ImpResultVo();
        List<String> fails=new LinkedList<>();
        log.info("impHistTaskList:batchid={},Count={}",batchid,paras.getAddVoList().size());

        for(HistTaskAddVo fiAdd:paras.getAddVoList()){
            FiTaskOldhist def=new FiTaskOldhist();
            BeanUtils.copyProperties(fiAdd,def);
            def.setBatchid(batchid);
            if(JPubUtils.IsTrimEmpty(def.getDousr())){
                def.setDousr($usrid);
            }
            def.setDodt(JPubUtils.StringToDate(fiAdd.getDodt()));
            def.setUpdt(new Date());
            def.setUpusr($usrid);

            fiTaskOldhistMapper.insert(def);

            ret++;
        }
        if(ret>0){
            fiImportHistService.AddImportHist(batchid, paras.getBatchdsc(), $usrid,
                    tempid, paras.getFilename(),
                    paras.getAddVoList().size(), ret);
        }

        impResultVo.setBatchid(batchid);
        impResultVo.setOkcnt(ret);
        impResultVo.setFailcnt(fails.size());
        impResultVo.setFaillist(fails);

        return impResultVo;
    }


    @Override
    public CmdResVo sendAiList(String $usrid,AiListSendVo paras)
    {
        IPage<AiListResVo> resVoIPage=null;
        String tempid=paras.getTempid();
        SimpleDateFormat sdf=new SimpleDateFormat("yyMMddHHmmssSSS");
        String batchid = "A"+sdf.format(new Date());
        if(JPubUtils.IsEqual(tempid,"ailist-ys")){
            resVoIPage=aiListMapper.quyAiListYs(new Page<>(1, 10000));
        }
        else if(JPubUtils.IsEqual(tempid,"ailist-mt")) {
            resVoIPage=aiListMapper.quyAiListMt(new Page<>(1, 10000));
        }
        else if(JPubUtils.IsEqual(tempid,"ailist-car")) {
            resVoIPage=aiListMapper.quyAiListCar(new Page<>(1, 10000));
        }
        else{
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        log.info("sendAiList:batchid={},Count={}",batchid,resVoIPage.getTotal());
        int okcount=(int)resVoIPage.getTotal();

        int[] pos=new int[1];
        resVoIPage.convert(u->{
            String dataid=batchid+"."+String.format("%d",pos[0]++);
            if(JPubUtils.IsEqual(tempid,"ailist-ys")) {
                dataid=dataid+"ys";
            }
            u.setDataId(dataid);
            return u;
        });

        List<AiListResVo> collect = resVoIPage.getRecords();
        HttpCommand.SendAiList(tempid,collect);

        if(okcount>0){
            fiImportHistService.AddImportHist(batchid, "Ai推送:"+batchid, $usrid, tempid, null, okcount, okcount);
            for(AiListResVo listResVo : collect){
                addTask($usrid, "SYS_AICALL", listResVo.getAcctNo(), EnumFiChannel.Ai.value,
                        listResVo.getMobileNumber(),batchid, listResVo.getDataId()
                );
                if(JPubUtils.IsEqual(tempid,"ailist-ys")&&JPubUtils.IsNotEmpty(listResVo.getAcctNo2())){
                    addTask($usrid, "SYS_AICALL", listResVo.getAcctNo2(), EnumFiChannel.Ai.value,
                            listResVo.getMobileNumber(), batchid,listResVo.getDataId()
                    );
                }
            }
        }

        return new CmdResVo(okcount,batchid);
    }

    @Override
    public CmdResVo saveAiListResult(String $usrid,AiCallRetVo paras)
    {
        log.info("saveAiListResult:",paras);
        String dataId=paras.getDataId();
        FiTask fiTask=selectJoinOne(FiTask.class,
                new MPJLambdaWrapper<FiTask>()
                        .ge(FiTask::getCrdt,JPubUtils.addDays(new Date(),-3))
                        .eq(FiTask::getChannel,EnumFiChannel.Ai.value)
                        .eq(FiTask::getCticallid,dataId)
                        .last("limit 1")
        );
        if(fiTask==null){
            log.info("saveAiListResult:{} NoFind",dataId);
            return new CmdResVo(0,dataId);
        }

        String tkstatus="R";
        String result="SUCCESS";
        String resultdsc=paras.getCallNote();
        if(!JPubUtils.StringToBool(paras.getCallSuccess())) {
            tkstatus = "F";
            result="FAIL";
            resultdsc=paras.getFailCause()+","+resultdsc;
        }

        saveTask(fiTask.getTasknumber(),$usrid,paras.getSendTimes(),result,resultdsc,paras.getPtp(),
                null,null,null,tkstatus
        );

        return new CmdResVo(1,dataId);
    }

    @Override
    public CmdResVo saveAsExcel(JSysUser user, FiTaskReqVo paras,HttpServletResponse response)
    {
        String $usrid=user.getUsrid();
        IPage<FiTaskResVo> pages=taskHist(user, paras);
        ArrayList arr=new ArrayList();

        String exptempid=JPubUtils.getExpTempID(paras.getExpfilename(),"催记列表");
        String filename=JPubUtils.getExpFileName(
                paras.getExpfilename(),exptempid
        );
        pages.convert(u->{
            HashMap map=JPubUtils.toExportMap(u);
            if(map!=null) arr.add(map);
            return u;
        });
        CmdResVo resVo=exportService.ToExcel(
                response,
                arr,
                paras.getExpidlist(),
                paras.getExpnamelist(),
                filename,
                $usrid
        );

        int okcount=resVo.getCount();
        if(okcount>0){
            fiImportHistService.AddExportHist(
                    resVo.getKeyId(),
                    $usrid,
                    exptempid,
                    filename,
                    okcount
            );
        }

        return resVo;
    }
//    @Override
//    public CmdResVo createBatchTask(String sql, CpCalllist cpCalllist){
//
//
//        return new CmdResVo(1);
//    }

    /**
     * 创建自动派发任务。
     * @param cfgRuleTaskSteps
     * @return
     */
    @Override
    public CmdResVo autoCreateTaskList(CfgRuleTaskSteps cfgRuleTaskSteps,String sql)
    {
        if( !cfgRuleTaskSteps.getActionCode().equals(EnumRuleStepAction.CAMPAIGN.getCode()))
            return new CmdResVo(0,"动作不匹配");
        //CpCalllist cpCalllist
        if(StringUtils.isEmpty(cfgRuleTaskSteps.getClid()))
            return new CmdResVo(0,"没有指定队列");
        CpCalllist cpCalllist = cpCalllistService.getById(cfgRuleTaskSteps.getClid());
        if(cpCalllist == null){
            return new CmdResVo(0,"没有找到队列"+cfgRuleTaskSteps.getClid());
        }
        //获取Batch号
        CpBatch cpBatch = cpBatchService.createBatch(cpCalllist,cfgRuleTaskSteps.getRuleStepId());
        Integer count = 0;
        if(cpCalllist.getChannel().equals(EnumFiChannel.Pd.value))
        {
            count = obCallCaseMapper.addBatchRecord(sql, cpCalllist.getClid(), cpBatch.getBatchid());
        }
        else if(cpCalllist.getChannel().equals(EnumFiChannel.Ai.value))
        {
            //获取模板
            List<MsgDefineField> msgDefineFields = msgDefineFieldService.getBaseMapper().selectList(
                    new LambdaQueryWrapper<MsgDefineField>().eq(MsgDefineField::getMsgid,cpCalllist.getSendmodel())
            );
            String selField = "";
            Integer fieldNum = 0;
            if(msgDefineFields != null) {
                for (MsgDefineField mf : msgDefineFields )
                {
                    selField += "," + mf.getFieldSql();
                    if( ++fieldNum == MAX_CUSTOMER_FIELD)
                        break;
                }
            }
            if( fieldNum < MAX_CUSTOMER_FIELD)
            {
                for( int i=0;i<(MAX_CUSTOMER_FIELD-fieldNum);i++)
                {
                    selField +=",''";
                }
            }
            count = obCallCaseMapper.addAiRecord(sql, cpCalllist.getClid(), cpBatch.getBatchid(), selField);
        }
        else {
            count = baseMapper.addBatchTask(sql, cpCalllist.getClid(), cpBatch.getBatchid().toString());
            //不写入短信表。
//            if (cpCalllist.getChannel().equals(EnumFiChannel.Sms.value)) {
//                smsSendphnMapper.sendBatchTask(cpBatch.getClid(), cpBatch.getBatchid().toString());
//            }
        }
        cpBatch.setCnt(count);
        cpBatchService.updateById(cpBatch);
        return new CmdResVo(count,"案件活动任务创建成功");

    }
}




